package karaokit.com;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import karaokit.com.KaraoKitEngine.SearchType;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

/**
 * this class represents file browser that allows the user to choose 
 * a media file or a lyrics file, and notify the KaraoKitEngine about the selection. 
 * most of the code is from: www.anddev.org
 */
public class FileBrowser extends ListActivity {

	private static KaraoKitEngine KarEngine = KaraoKitEngine.GetEngine();
	private enum DISPLAYMODE{ ABSOLUTE, RELATIVE; }

	private final DISPLAYMODE displayMode = DISPLAYMODE.RELATIVE;
	private List<String> directoryEntries = new ArrayList<String>();
	private File currentDirectory = new File("/");
	private SearchType curSearchType;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		browseTo(new File(KaraoKitEngine.KaraoKitDir));
	}
	
	/**
	 * This function browses up one level
	 * according to the field: currentDirectory
	 */
	private void upOneLevel(){
		if(this.currentDirectory.getParent() != null)
			this.browseTo(this.currentDirectory.getParentFile());
	}

	/**
	 * browses to the given directory or selects a file.
	 * @param aDirectory browses to the given directory.
	 */
	private void browseTo(final File aDirectory){
		if (aDirectory.isDirectory()){ //browse into it
			Toast.makeText(this, aDirectory.getAbsolutePath(), Toast.LENGTH_SHORT).show();
			this.currentDirectory = aDirectory;
			curSearchType =  KarEngine.getSearchType();
			if (KarEngine.getSearchType() == SearchType.Media)
				fill(aDirectory.listFiles(KaraoKitEngine.MediaFilesFilter));
			else
				fill(aDirectory.listFiles(KaraoKitEngine.LyricsFilter));
		} 
		else {	// the user has selected a file
			
			OnClickListener browseForLyricsButtonListener = new OnClickListener(){				
				// a media file has been selected and the user wants to browse for lyrics too
				public void onClick(DialogInterface arg0, int arg1) {					
					KarEngine.fileSelected(FileBrowser.this, aDirectory, false);					
					KarEngine.setSearchType(SearchType.Lyrics);
					Intent i = new Intent(FileBrowser.this, FileBrowser.class);
					FileBrowser.this.startActivity(i);
				}
			};
			OnClickListener noLyricsButtonListener = new OnClickListener(){		
				// a media file has been selected and the user wants to end the operation
				public void onClick(DialogInterface arg0, int arg1) {					
					KarEngine.fileSelected(FileBrowser.this, aDirectory, true);
				}
			};
			OnClickListener cancelButtonListener = new OnClickListener(){
				public void onClick(DialogInterface arg0, int arg1) {
					// Do nothing
				}
			};

			if (KarEngine.getSearchType() == SearchType.Media) {
				new AlertDialog.Builder(FileBrowser.this)
				.setTitle("Question")
				.setMessage("Do you want to browse for lyrics too?\n")
				.setPositiveButton("Sure", browseForLyricsButtonListener)
				.setNeutralButton("No thanks", noLyricsButtonListener)
				.setNegativeButton("Cancel", cancelButtonListener)
						.show();
			}
			else  {// the user chose a lyric file and is ready to play 
				KarEngine.fileSelected(FileBrowser.this, aDirectory, true);
			}
		}
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		KarEngine.setSearchType(curSearchType);
		KarEngine.setCurLyrics(null);
		Toast.makeText(this, "Browsing for " + curSearchType, Toast.LENGTH_SHORT).show();
	}
	
	/**
	 * updates the list of current files to be viewed by the user.
	 * @param files
	 */
	private void fill(File[] files) {
		this.directoryEntries.clear();
		// Add the "." and the ".." == 'Up one level'
		try {
			Thread.sleep(10);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		this.directoryEntries.add(".");

		if(this.currentDirectory.getParent() != null)
			this.directoryEntries.add("..");

		switch(this.displayMode){
		case ABSOLUTE:
			for (File file : files){
				this.directoryEntries.add(file.getPath());
			}
			break;
		case RELATIVE: // On relative Mode, we have to add the current-path to the beginning
			int currentPathStringLenght = this.currentDirectory.getAbsolutePath().length();
			for (File file : files){
				this.directoryEntries.add(file.getAbsolutePath().substring(currentPathStringLenght));
			}
			break;
		}

		ArrayAdapter<String> directoryList = new ArrayAdapter<String>(this,
				R.layout.file_row, this.directoryEntries);

		this.setListAdapter(directoryList);
	}

	/**
	 * deals with a press on an item in the viewed list of files.
	 */
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		int selectionRowID = position;
		String selectedFileString = this.directoryEntries.get(selectionRowID);
		if (selectedFileString.equals(".")) {			
			this.browseTo(new File("/")); // go to root dir
		} else if (selectedFileString.equals("..")){
			this.upOneLevel();
		} else {
			File clickedFile = null;
			switch(this.displayMode){
			case RELATIVE:
				clickedFile = new File(this.currentDirectory.getAbsolutePath()
						+ this.directoryEntries.get(selectionRowID));
				break;
			case ABSOLUTE:
				clickedFile = new File(this.directoryEntries.get(selectionRowID));
				break;
			}
			if (clickedFile != null)
				this.browseTo(clickedFile);
		}
	}
}